#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
天翼云盘TV版SDK工具模块
包含公共方法：文件大小格式化、时间格式化、签名生成、加密解密等
"""

import hashlib
import hmac
import time
import uuid
import re
import binascii
import random
from typing import Dict, Optional
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5, AES
from Crypto.Util.Padding import pad

# 常量定义
APP_ID = "8025431004"
VERSION = "6.2"
PC = "TELEPC"
CHANNEL_ID = "web_cloud.189.cn"


class FormatUtils:
    """格式化工具类"""
    
    @staticmethod
    def format_size(size: int) -> str:
        """格式化文件大小"""
        if size < 1024:
            return f"{size} B"
        elif size < 1024 * 1024:
            return f"{size / 1024:.1f} KB"
        elif size < 1024 * 1024 * 1024:
            return f"{size / (1024 * 1024):.1f} MB"
        else:
            return f"{size / (1024 * 1024 * 1024):.1f} GB"
    
    @staticmethod
    def format_time(timestamp: str) -> str:
        """格式化时间"""
        try:
            if len(timestamp) == 13:  # 毫秒时间戳
                timestamp = timestamp[:10]
            time_obj = time.localtime(int(timestamp))
            return time.strftime("%Y-%m-%d %H:%M", time_obj)
        except:
            return timestamp


class TimeUtils:
    """时间工具类"""
    
    @staticmethod
    def timestamp() -> int:
        """获取当前时间戳"""
        return int(time.time())
    
    @staticmethod
    def get_http_date_str() -> str:
        """获取HTTP日期字符串"""
        return time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime())


class ClientUtils:
    """客户端工具类"""
    
    @staticmethod
    def client_suffix() -> Dict[str, str]:
        """获取客户端后缀信息"""
        return {
            "clientType": PC,
            "version": VERSION,
            "channelId": CHANNEL_ID,
            "model": "web",
            "osFamily": "web"
        }


class CryptoUtils:
    """加密工具类"""
    
    @staticmethod
    def rsa_encrypt(public_key: str, orig_data: str) -> str:
        """RSA加密"""
        try:
            public_key = f"-----BEGIN PUBLIC KEY-----\n{public_key}\n-----END PUBLIC KEY-----"
            rsa_key = RSA.importKey(public_key)
            cipher = PKCS1_v1_5.new(rsa_key)
            encrypted_data = cipher.encrypt(orig_data.encode('utf-8'))
            return binascii.b2a_hex(encrypted_data).decode('utf-8')
        except Exception as e:
            print(f"RSA加密失败: {e}")
            return ""
    
    @staticmethod
    def aes_ecb_encrypt(data: str, key: str) -> str:
        """AES ECB加密"""
        try:
            key = key.encode('utf-8')
            data = data.encode('utf-8')
            
            cipher = AES.new(key, AES.MODE_ECB)
            padded_data = pad(data, AES.block_size)
            encrypted_data = cipher.encrypt(padded_data)
            
            return binascii.b2a_hex(encrypted_data).decode('utf-8')
        except Exception as e:
            print(f"AES加密失败: {e}")
            return ""


class SignatureUtils:
    """签名工具类"""
    
    @staticmethod
    def signature_of_hmac(session_secret: str, session_key: str, operate: str, 
                         full_url: str, date_of_gmt: str, params: str = "") -> str:
        """生成HMAC签名"""
        plain_text = f"{session_key}\n{full_url}\n{operate}\n{params}\n{date_of_gmt}"
        return hmac.new(
            session_secret.encode('utf-8'),
            plain_text.encode('utf-8'),
            hashlib.sha1
        ).hexdigest().upper()
    
    @staticmethod
    def signature_header(url: str, method: str, token_info: Dict, params: str = "", 
                        is_family: bool = False) -> Dict[str, str]:
        """生成签名头"""
        date_str = TimeUtils.get_http_date_str()
        session_key = token_info.get('sessionKey', '')
        session_secret = token_info.get('sessionSecret', '')
        
        signature = SignatureUtils.signature_of_hmac(
            session_secret, session_key, method, url, date_str, params
        )
        
        return {
            'SessionKey': session_key,
            'Signature': signature,
            'Date': date_str
        }
    
    @staticmethod
    def encrypt_params(params: Dict[str, str], token_info: Dict, is_family: bool = False) -> str:
        """加密参数"""
        try:
            import json
            params_str = json.dumps(params, separators=(',', ':'))
            
            # 使用AES加密
            key = token_info.get('sessionSecret', '')[:16]  # 取前16位作为密钥
            encrypted = CryptoUtils.aes_ecb_encrypt(params_str, key)
            return encrypted
        except Exception as e:
            print(f"参数加密失败: {e}")
            return ""


class CacheUtils:
    """缓存工具类"""
    
    @staticmethod
    def is_cache_valid(cache_time: float, timeout: int = 300) -> bool:
        """检查缓存是否有效"""
        return time.time() - cache_time < timeout
    
    @staticmethod
    def get_cache_key(folder_id: str, is_family: bool) -> str:
        """获取缓存键"""
        prefix = "family" if is_family else "personal"
        return f"{prefix}_{folder_id}"


__all__ = [
    'FormatUtils',
    'TimeUtils', 
    'ClientUtils',
    'CryptoUtils',
    'SignatureUtils',
    'CacheUtils'
]